//
//  connection.hpp
//  fibio
//
//  Created by Chen Xu on 15/09/11.
//  Copyright (c) 2015 0d0a.com. All rights reserved.
//

#ifndef fibio_db_mysql_connection_hpp
#define fibio_db_mysql_connection_hpp

#include <cppconn/connection.h>

namespace fibio {
namespace db {
namespace mysql {

class MySQL_DatabaseMetaData;

class MySQL_Connection : public sql::Connection
{
public:
    virtual ~MySQL_Connection();

    virtual void clearWarnings() override;

    virtual sql::Statement* createStatement() override;

    virtual void close() override;

    virtual void commit() override;

    virtual bool getAutoCommit() override;

    virtual sql::SQLString getCatalog() override;

    virtual sql::Driver* getDriver() override;

    virtual sql::SQLString getSchema() override;

    virtual sql::SQLString getClientInfo() override;

    virtual void getClientOption(const sql::SQLString& optionName, void* optionValue) override;

    virtual sql::SQLString getClientOption(const sql::SQLString& optionName) override;

    virtual sql::DatabaseMetaData* getMetaData() override;

    virtual sql::enum_transaction_isolation getTransactionIsolation() override;

    virtual const sql::SQLWarning* getWarnings() override;

    virtual bool isClosed() override;

    virtual bool isReadOnly() override;

    virtual bool isValid() override;

    virtual bool reconnect() override;

    virtual sql::SQLString nativeSQL(const sql::SQLString& sql) override;

    virtual sql::PreparedStatement* prepareStatement(const sql::SQLString& sql) override;

    virtual sql::PreparedStatement* prepareStatement(const sql::SQLString& sql,
                                                     int autoGeneratedKeys) override;

    virtual sql::PreparedStatement* prepareStatement(const sql::SQLString& sql,
                                                     int* columnIndexes) override;

    virtual sql::PreparedStatement* prepareStatement(const sql::SQLString& sql,
                                                     int resultSetType,
                                                     int resultSetConcurrency) override;

    virtual sql::PreparedStatement* prepareStatement(const sql::SQLString& sql,
                                                     int resultSetType,
                                                     int resultSetConcurrency,
                                                     int resultSetHoldability) override;

    virtual sql::PreparedStatement* prepareStatement(const sql::SQLString& sql,
                                                     sql::SQLString columnNames[]) override;

    virtual void releaseSavepoint(sql::Savepoint* savepoint) override;

    virtual void rollback() override;

    virtual void rollback(sql::Savepoint* savepoint) override;

    virtual void setAutoCommit(bool autoCommit) override;

    virtual void setCatalog(const sql::SQLString& catalog) override;

    virtual void setSchema(const sql::SQLString& catalog) override;

    virtual sql::Connection* setClientOption(const sql::SQLString& optionName,
                                             const void* optionValue) override;

    virtual sql::Connection* setClientOption(const sql::SQLString& optionName,
                                             const sql::SQLString& optionValue) override;

    virtual void setHoldability(int holdability) override;

    virtual void setReadOnly(bool readOnly) override;

    virtual sql::Savepoint* setSavepoint() override;

    virtual sql::Savepoint* setSavepoint(const sql::SQLString& name) override;

    virtual void setTransactionIsolation(sql::enum_transaction_isolation level) override;

private:
    MySQL_Connection(sql::Driver* drv,
                     sql::Connection* impl,
                     std::shared_ptr<fibers::foreign_thread_pool> executor);
    sql::Driver* driver_;
    std::unique_ptr<sql::Connection> impl_;
    struct deleter
    {
        void operator()(MySQL_DatabaseMetaData*);
    };
    std::unique_ptr<MySQL_DatabaseMetaData, deleter> dbmeta_;
    std::shared_ptr<fibers::foreign_thread_pool> executor_;
    friend class MySQL_Driver;
};

} // End of namespace mysql
} // End of namespace db
} // End of namespace fibio

#endif // !defined(fibio_db_mysql_connection_hpp)
